package handlers;
import java.io.IOException;
import java.io.InputStream;

import org.apache.html.dom.HTMLDocumentImpl;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.cyberneko.html.parsers.DOMFragmentParser;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class NekoHTMLHandler implements DocumentHandler {
	
	private DOMFragmentParser parser = new DOMFragmentParser();
	
	@SuppressWarnings("deprecation")
	public Document getDocument(InputStream is) throws Exception {
		DocumentFragment node =	new HTMLDocumentImpl().createDocumentFragment();
		try {
			parser.parse(new InputSource(is), node);
		}
		catch (IOException e) {
			throw new Exception("Cannot parse HTML document: ", e);
		}
		catch (SAXException e) {
			throw new Exception("Cannot parse HTML document: ", e);
	}
		Document doc =	new Document();
		StringBuffer sb = new StringBuffer();
		getText(sb, node, "title");
		String title = sb.toString();
		sb.setLength(0);
		getText(sb, node);
		String text = sb.toString();
		if ((title != null) && (!title.equals(""))) {
			//doc.add(Field.Text("title", title));
			doc.add(new Field("title", title, Field.Store.YES,Field.Index.TOKENIZED));
		}
		if ((text != null) && (!text.equals(""))) {
			//doc.add(Field.Text("body", text));
			doc.add(new Field("contents", text, Field.Store.YES,Field.Index.TOKENIZED));
		}
		return doc;
	}
	
	private void getText(StringBuffer sb, Node node) {
		if (node.getNodeType() == Node.TEXT_NODE) {
			sb.append(node.getNodeValue());
		}
		NodeList children = node.getChildNodes();
		if (children != null) {
			int len = children.getLength();
			for (int i = 0; i < len; i++) {
				getText(sb, children.item(i));
			}
		}
	}
	private boolean getText(StringBuffer sb, Node node,String element) {
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			if (element.equalsIgnoreCase(node.getNodeName())) {
				getText(sb, node);
				return true;
			}
		}
		NodeList children = node.getChildNodes();
		if (children != null) {
			int len = children.getLength();
			for (int i = 0; i < len; i++) {
				if (getText(sb, children.item(i), element)) {
					return true;
				}
			}
		}
		return false;
	}
	
}
